home *** CD-ROM | disk | FTP | other *** search
- /*
- * sync.h --
- *
- * Definitions of routines for the synchronization module.
- * The synchronization module provides locks and condition
- * variables to other modules, plus a low level binary semaphore
- * needed to synchronize with interrupt handlers.
- *
- * The behavior of the sync module can be modified using compiler
- * variables. These variables will change the structure of locks and
- * how the locks are used. In general it is not a good idea to link
- * modules that have been compiled with different versions of locks.
- *
- * <default> - semaphores and locks have fields that contain a
- * character string name, the pc where the lock was
- * last locked, and a pointer to the pcb of the last
- * lock holder. The locking operation is slower because
- * these fields must be updated.
- *
- * CLEAN_LOCK - locks do not contain any extra fields. This version
- * of locks is intended for benchmarking the kernel.
- *
- * LOCKREG - locks are registered so that the information stored
- * in them can be retrieved. In addition to the fields
- * in the default version of locks, a count of hits
- * and misses on each lock is kept. Lock registration
- * must be done when the lock is created and destroyed.
- * The locking operation is slower due to the hit/miss
- * counters. A count is kept for each spin lock that
- * records the number of times a processor spun waiting
- * for the lock.
- *
- * LOCKDEP - Each lock keeps a list of locks that were held when
- * it was locked in addition to the information kept
- * in the LOCKREG version. Locks compiled with LOCKDEP
- * will get very large. This information can be used to
- * construct a graph of the locking behavior of the
- * kernel. Locking and unlocking is slowed down due
- * to the necessity of recording previously held lock.
- *
- *
- * Copyright 1986 Regents of the University of California
- * All rights reserved.
- *
- * $Header: /cdrom/src/kernel/Cvsroot/kernel/sync/sync.h,v 9.12 91/08/15 17:56:24 jhh Exp $ SPRITE (Berkeley)
- */
-
- #ifndef _SYNC
- #define _SYNC
-
- #include <sprite.h>
- #include <list.h>
-
- #ifdef KERNEL
- #include <syncTypes.h>
- #include <mach.h>
- #include <proc.h>
- #else
- #include <kernel/syncTypes.h>
- #include <kernel/mach.h>
- #include <kernel/proc.h>
- #endif /* KERNEL */
-
- /*
- * These include files are needed by the SysV sema support.
- */
- #include <sys/types.h>
- #include <sys/ipc.h>
- #include <sys/sem.h>
-
- /*
- * Exported procedures and variables of the sync module.
- */
-
- extern Sync_Instrument sync_Instrument[MACH_MAX_NUM_PROCESSORS];
- extern Sync_Instrument *sync_InstrumentPtr[MACH_MAX_NUM_PROCESSORS];
- extern int sync_BusyWaits;
-
- extern void Sync_Init _ARGS_((void));
- extern ReturnStatus Sync_GetLock _ARGS_((Sync_Lock *lockPtr));
- extern ReturnStatus Sync_Unlock _ARGS_((Sync_Lock *lockPtr));
- extern ReturnStatus Sync_SlowLock _ARGS_((register Sync_Lock *lockPtr));
- extern Boolean Sync_SlowWait _ARGS_((Sync_Condition *conditionPtr,
- Sync_Lock *lockPtr, Boolean wakeIfSignal));
- extern ReturnStatus Sync_SlowBroadcast _ARGS_((unsigned int event,
- int *waitFlagPtr));
-
- extern Boolean Sync_SlowMasterWait _ARGS_((unsigned int event,
- Sync_Semaphore *mutexPtr, Boolean wakeIfSignal));
- extern void Sync_UnlockAndSwitch _ARGS_((Sync_Lock *lockPtr, Proc_State state));
- extern void Sync_WakeWaitingProcess _ARGS_((register Proc_ControlBlock *procPtr));
- extern void Sync_WakeupProcess _ARGS_((Timer_Ticks time, ClientData procAddress));
-
- extern void Sync_GetWaitToken _ARGS_((Proc_PID *pidPtr, int *tokenPtr));
- extern void Sync_SetWaitToken _ARGS_((Proc_ControlBlock *procPtr, int waitToken));
-
- extern Boolean Sync_WaitTime _ARGS_((Time time));
- extern Boolean Sync_WaitTimeInTicks _ARGS_((Timer_Ticks time));
- extern Boolean Sync_WaitTimeInterval _ARGS_((unsigned int interval));
-
- extern Boolean Sync_ProcWait _ARGS_((Sync_Lock *lockPtr, Boolean wakeIfSignal));
- extern void Sync_ProcWakeup _ARGS_((Proc_PID pid, int token));
-
- extern ReturnStatus Sync_RemoteNotify _ARGS_((Sync_RemoteWaiter *waitPtr));
- extern ReturnStatus Sync_RemoteNotifyStub _ARGS_((ClientData srvToken,
- int clientID, int command, Rpc_Storage *storagePtr));
-
- extern ReturnStatus Sync_SlowLockStub _ARGS_((Sync_UserLock *lockPtr));
- extern ReturnStatus Sync_SlowWaitStub _ARGS_((unsigned int event,
- Sync_UserLock *lockPtr, Boolean wakeIfSignal));
- extern ReturnStatus Sync_SlowBroadcastStub _ARGS_((unsigned int event,
- int *waitFlagPtr));
-
- extern void Sync_PrintStat _ARGS_((void));
-
- extern void Sync_LockStatInit _ARGS_((void));
- extern void SyncAddPriorInt _ARGS_((int type, int *priorCountPtr,
- int *priorTypes, Address lockPtr,
- Proc_ControlBlock *pcbPtr));
-
- extern void SyncDeleteCurrentInt _ARGS_((Address lockPtr,
- Proc_ControlBlock *pcbPtr));
- extern void SyncMergePriorInt _ARGS_((int priorCount, int *priorTypes,
- Sync_RegElement *regPtr));
- extern void Sync_RegisterInt _ARGS_((Address lock));
- extern void Sync_CheckoutInt _ARGS_((Address lock));
-
- extern ReturnStatus Sync_SemgetStub _ARGS_((long key, int nsems, int semflg,
- int *retValOut));
- extern ReturnStatus Sync_SemopStub _ARGS_((int semid, struct sembuf *sopsIn,
- int nsops, int retValOut));
-
- extern ReturnStatus Sync_SemctlStub _ARGS_((int semid, int semnum, int cmd,
- union semun arg, int *retValOut));
- extern ReturnStatus Sync_SemStruct _ARGS_((int id, int *perm,
- Sync_SysVSem **retPtr));
-
- extern ReturnStatus Sync_Sleep _ARGS_((Time time));
- extern void Sync_SemInit _ARGS_((void));
-
- extern ReturnStatus Sync_GetLockStats _ARGS_((int size, Address argPtr));
- extern ReturnStatus Sync_ResetLockStats _ARGS_((void));
-
- extern void Sync_RemoveWaiter _ARGS_((Proc_ControlBlock *procPtr));
-
- extern Sync_RegElement *regQueuePtr;
-
-
-
- /*
- *----------------------------------------------------------------------------
- *
- * MASTER_LOCK --
- *
- * Enter a critical section guarded by a binary semaphore.
- * This is for use in a multiprocessor environment
- * within the synchronization module, and in other
- * modules that interact with interrupt-time routines.
- * (All other synchronization should be done with Monitors.)
- *
- * Interrupts are disabled on the local processor to prevent
- * a preemptive context switch. The semaphore is checked
- * with a Mach_TestAndSet atomic operation in a busy wait
- * to prevent races with other processors.
- *
- * For uniprocessor debugging, panic when the lock is held (otherwise
- * we get an infinite loop).
- *
- * There are three versions of this macro. This is due to the different
- * sizes of locks. There is only one uniprocessor version. It uses
- * other macros that are modified by compiler variables. There are
- * two versions of the multiprocessor implementation. The first is
- * used when we are keeping hit/miss ratios and the second is for
- * when we are not.
- *
- * Results:
- * None.
- *
- * Side effects:
- * The semaphore has its value set from 0 to 1.
- * Interrupts are disabled.
- *
- *----------------------------------------------------------------------------
- */
-
- #if (MACH_MAX_NUM_PROCESSORS == 1) /* uniprocessor implementation */
-
- #define MASTER_LOCK(semaphore) \
- { \
- sync_Instrument[Mach_GetProcessorNumber()].numLocks++; \
- DISABLE_INTR(); \
- if ((semaphore)->value == 1) { \
- SyncDeadlockPanic((semaphore)); \
- } else { \
- (semaphore)->value++;\
- Sync_SemRegister(semaphore); \
- Sync_RecordHit(semaphore); \
- Sync_StoreDbgInfo(semaphore, TRUE); \
- Sync_AddPrior(semaphore); \
- }\
- }
-
- #else /* multiprocessor implementation */
-
- #ifdef LOCKREG
-
- #define MASTER_LOCK(semaphore) \
- { \
- int missFlag = 0;\
- int pnum = Mach_GetProcessorNumber();\
- int type = ((semaphore)->type > 0) ? (semaphore)->type : 0;\
- sync_InstrumentPtr[pnum]->numLocks++; \
- DISABLE_INTR(); \
- for(;;) { \
- /* \
- * wait until semaphore looks free -- avoid bouncing between \
- * processor caches. \
- */ \
- while((semaphore)->value != 0) { \
- if (missFlag == 0) { \
- missFlag = 1; \
- } \
- sync_InstrumentPtr[pnum]->spinCount[type]++;\
- } \
- if(Mach_TestAndSet(&((semaphore)->value)) == 0) { \
- break; \
- } else if (missFlag == 0) { \
- missFlag = 1; \
- } \
- sync_InstrumentPtr[pnum]->spinCount[type]++;\
- } \
- if(missFlag == 1) { \
- Sync_RecordMiss(semaphore); \
- } \
- Sync_SemRegister(semaphore); \
- Sync_RecordHit(semaphore) ; \
- Sync_StoreDbgInfo(semaphore, TRUE); \
- Sync_AddPrior(semaphore); \
- }
-
- #else /* LOCKREG -- These are the clean versions of the macros */
-
- #define MASTER_LOCK(semaphore) \
- { \
- sync_InstrumentPtr[Mach_GetProcessorNumber()]->numLocks++; \
- DISABLE_INTR(); \
- for(;;) { \
- /* \
- * wait until semaphore looks free -- avoid bouncing between \
- * processor caches. \
- */ \
- while((semaphore)->value != 0) { \
- } \
- if(Mach_TestAndSet(&((semaphore)->value)) == 0) { \
- break; \
- } \
- } \
- }
-
- #endif /* LOCKREG */
- #endif /*multiprocessor implementation */
-
-
- /*
- *----------------------------------------------------------------------------
- *
- * MASTER_UNLOCK --
- *
- * Leave a critical section guarded by a binary semaphore. This is for
- * use in a multiprocessor environment. Interrupts are enabled and the
- * semaphore value is reset to 0 to allow other processors entry into
- * the critical section.
- *
- * Results:
- * None.
- *
- * Side effects:
- * The semaphore has its value reset to 0.
- * Interrupts are enabled.
- *
- *----------------------------------------------------------------------------
- */
-
- #define MASTER_UNLOCK(semaphore) \
- { \
- int pnum = Mach_GetProcessorNumber();\
- sync_InstrumentPtr[pnum]->numUnlocks++; \
- (semaphore)->value = 0; \
- SyncDeleteCurrent(semaphore); \
- if (!Mach_AtInterruptLevel()) { \
- --mach_NumDisableIntrsPtr[pnum]; \
- if (mach_NumDisableIntrsPtr[pnum] == 0) { \
- Mach_EnableIntr(); \
- } \
- } \
- }
-
-
- /*
- * Condition variables can be used in critical sections guarded by
- * MASTER_LOCK and MASTER_UNLOCK. Sync_MasterWait and
- * Sync_MasterBroadcast are the analogues of Sync_Wait and
- * Sync_Broadcast.
- */
-
- /*
- *----------------------------------------------------------------------
- *
- * Sync_MasterWait --
- *
- * Wait on an event with a master lock held.
- * This has the same semantics as Sync_Wait except
- * that the lock release when the process sleeps is
- * a master lock.
- *
- * Results:
- * None.
- *
- * Side effects:
- * The process gets descheduled, the master lock gets released
- * and then reacquired after the condition is notified.
- *
- *----------------------------------------------------------------------
- */
-
- #define Sync_MasterWait(conditionPtr, mutexPtr, wakeIfSignal) \
- { \
- (conditionPtr)->waiting = TRUE; \
- (void) Sync_SlowMasterWait((unsigned int) conditionPtr, mutexPtr, \
- wakeIfSignal); \
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * Sync_MasterBroadcast --
- *
- * Notify an event, like Sync_Broadcast except it
- * should be used with a master lock held because of the
- * check on conditionPtr->waiting.
- *
- * (This could verify that a master lock is held.)
- *
- * Results:
- * None.
- *
- * Side effects:
- * Notify all processes waiting on the event.
- *
- *----------------------------------------------------------------------
- */
-
- #define Sync_MasterBroadcast(conditionPtr) \
- { \
- if ((conditionPtr)->waiting == TRUE) { \
- (void) Sync_SlowBroadcast((unsigned int)conditionPtr, \
- &(conditionPtr)->waiting); \
- } \
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * UNLOCK_AND_SWITCH --
- *
- * Macro to call the internal routine to release the monitor lock and
- * then context switch.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Lock released and process context switched.
- *
- *----------------------------------------------------------------------
- */
-
- #define UNLOCK_MONITOR_AND_SWITCH(state) Sync_UnlockAndSwitch(LOCKPTR, state)
-
- /*
- * The initialization routines are used to initialize a semaphore.
- * The name parameter is the name of the semaphore and is used to
- * distinguish between types of locks. If you want the statistics
- * (hit, miss, etc) for two semaphores to be shared then give them the
- * same name. An example might be locks around file handles, where it
- * makes more sense to have the statistics for all the locks as a whole,
- * rather than just one lock. Also beware that no distinction is made
- * between locks and semaphores when determining types -- if they have
- * the same name they have the same type.
- * Sync_SemClear should be called when a semaphore is being deallocated
- * and will be no longer used. Currently all this routine does is to
- * take the statistics associated with the semaphore and merge them in
- * with those for the type as a whole.
- */
-
- /*
- *----------------------------------------------------------------------
- *
- * Sync_SemRegister --
- *
- * Register a semaphore.
- *
- *----------------------------------------------------------------------
- */
- #define Sync_SemRegister Sync_LockRegister
-
- /*
- *----------------------------------------------------------------------
- *
- * Sync_SemClear
- *
- * Clear a semaphore.
- *
- *----------------------------------------------------------------------
- */
- #define Sync_SemClear Sync_LockClear
-
-
- /*
- *----------------------------------------------------------------------
- *
- * Sync_SemInitStatic --
- *
- * Initializes the fields of a semaphore in an initialization statement.
- * Ex:
- * static Sync_Semaphore foo = Sync_SemInitStatic("foo");
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- #ifdef CLEAN_LOCK
-
- #define Sync_SemInitStatic(name) \
- {0}
-
- #else
- #ifdef LOCKDEP
-
- #define Sync_SemInitStatic(name) \
- {0,0,0, SYNC_SEMAPHORE, 0, SYNC_LISTINFO_INIT, name,(Address) NIL, \
- (Proc_ControlBlock *) NIL, 0}
-
- #else
-
- #ifdef LOCKREG
-
- #define Sync_SemInitStatic(name) \
- {0,0,0, SYNC_SEMAPHORE, 0, SYNC_LISTINFO_INIT, name,(Address) NIL, \
- (Proc_ControlBlock *) NIL}
- #else
- #define Sync_SemInitStatic(name) \
- {0,name, (Address) NIL, (Proc_ControlBlock *) NIL}
-
- #endif /* LOCKREG */
- #endif /* LOCKDEP */
- #endif /* CLEAN_LOCK */
-
-
- /*
- *----------------------------------------------------------------------
- *
- * Sync_SemInitDynamic --
- *
- * Initializes the fields of a semaphore during program execution.
- * Ex:
- * Sync_SemInitDynamic(foo,"foo");
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- #ifdef CLEAN_LOCK
-
- #define Sync_SemInitDynamic(sem,semName) \
- { (sem)->value = 0; }
-
- #else
- #ifdef LOCKDEP
-
- #define Sync_SemInitDynamic(sem, semName) { \
- (sem)->value = (sem)->miss = 0; (sem)->name = semName; \
- (sem)->hit = 0; (sem)->type = 0; \
- (sem)->holderPC = (Address)NIL; (sem)->class = SYNC_SEMAPHORE;\
- (sem)->holderPCBPtr = (Proc_ControlBlock *) NIL; \
- (sem)->priorCount = 0;\
- List_InitElement(&(sem)->listInfo.links);\
- }
-
-
- #else
-
- #ifdef LOCKREG
-
- #define Sync_SemInitDynamic(sem, semName) { \
- (sem)->value = (sem)->miss = 0; (sem)->name = semName; \
- (sem)->hit = 0; (sem)->type = 0;\
- (sem)->holderPC = (Address)NIL; (sem)->class = SYNC_SEMAPHORE;\
- (sem)->holderPCBPtr = (Proc_ControlBlock *) NIL; \
- List_InitElement(&(sem)->listInfo.links);\
- }
-
- #else
- #define Sync_SemInitDynamic(sem, semName) { \
- (sem)->value = 0; (sem)->name = semName; \
- (sem)->holderPC = (Address)NIL;\
- (sem)->holderPCBPtr = (Proc_ControlBlock *) NIL; \
- }
- #endif /* LOCKREG */
- #endif /* LOCKDEP */
- #endif /* CLEAN_LOCK */
-
-
- /*
- *----------------------------------------------------------------------
- *
- * Sync_LockInitStatic --
- *
- * Initializes the fields of a lock in an initialization statement.
- * Ex:
- * static Sync_Lock foo = Sync_LockInitStatic("foo");
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
- #ifdef CLEAN_LOCK
-
- #define Sync_LockInitStatic(name) {0,0}
-
- #else
- #ifdef LOCKDEP
-
- #define Sync_LockInitStatic(name) \
- {0,0,0,SYNC_LOCK, 0, SYNC_LISTINFO_INIT, 0, name, (Address) NIL, \
- (Proc_ControlBlock *) NIL,0}
-
- #else
-
- #ifdef LOCKREG
-
- #define Sync_LockInitStatic(name) \
- {0,0,0,SYNC_LOCK, 0, SYNC_LISTINFO_INIT, 0, name, (Address) NIL, \
- (Proc_ControlBlock *) NIL}
-
- #else
- #define Sync_LockInitStatic(name) \
- {0,0,name, (Address) NIL, (Proc_ControlBlock *) NIL}
-
-
- #endif /* LOCKREG */
- #endif /* LOCKDEP */
- #endif /* CLEAN_LOCK */
-
-
- /*
- *----------------------------------------------------------------------
- *
- * Sync_LockInitDynamic --
- *
- * Initializes the fields of a lock during program execution.
- * Ex:
- * Sync_LockInitDynamic(foo,"foo");
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- #ifdef CLEAN_LOCK
-
- #define Sync_LockInitDynamic(lock, lockName) \
- {(lock)->inUse = (lock)->waiting = 0;}
-
- #else
- #ifdef LOCKDEP
-
- #define Sync_LockInitDynamic(lock, lockName) { \
- (lock)->inUse = (lock)->waiting = 0; (lock)->class = SYNC_LOCK;\
- (lock)->hit = (lock)->miss = 0; (lock)->name = lockName; \
- (lock)->holderPC = (Address) NIL; (lock)->type = 0; \
- (lock)->holderPCBPtr = (Proc_ControlBlock *) NIL; \
- (lock)->priorCount = 0;\
-
- #else
-
- #ifdef LOCKREG
-
- #define Sync_LockInitDynamic(lock, lockName) { \
- (lock)->inUse = (lock)->waiting = 0; (lock)->class = SYNC_LOCK;\
- (lock)->hit = (lock)->miss = 0; (lock)->name = lockName; \
- (lock)->holderPC = (Address) NIL; (lock)->type = 0; \
- (lock)->holderPCBPtr = (Proc_ControlBlock *) NIL; \
- }
-
- #else
- #define Sync_LockInitDynamic(lock, lockName) { \
- (lock)->inUse = (lock)->waiting = 0; (lock)->name = lockName; \
- (lock)->holderPC = (Address) NIL; \
- (lock)->holderPCBPtr = (Proc_ControlBlock *) NIL; \
- }
-
- #endif /* LOCKREG */
- #endif /* LOCKDEP */
- #endif /* CLEAN_LOCK */
-
-
- /*
- *----------------------------------------------------------------------
- *
- * Sync_IsRegistered --
- *
- * Returns true if a lock or semaphore has already been registered. If
- * LOCKREG is not defined then this macro always returns FALSE.
- *
- * Results:
- * TRUE if lock or semaphore registered.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- #ifdef LOCKREG
-
- #define Sync_IsRegistered(lock) \
- (((lock)->type > 0) ? TRUE : FALSE)
-
- #else /* LOCKREG */
-
- #define Sync_IsRegistered(lock) FALSE
-
- #endif /* LOCKREG */
-
- /*
- *----------------------------------------------------------------------
- *
- * Sync_LockRegister --
- *
- * Used to add a lock to the registration database.
- * If LOCKREG is not defined then this macro does nothing.
- *
- * Results:
- * None.
- *
- * Side effects:
- * The lock is registered.
- *
- *----------------------------------------------------------------------
- */
- #ifdef LOCKREG
-
- #define Sync_LockRegister(lock) \
- { \
- if (!Sync_IsRegistered((Sync_Lock *) lock)) { \
- Sync_RegisterInt((Address) (lock)); \
- } \
- }
-
- #else /* LOCKREG */
-
- #define Sync_LockRegister(lock) {}
-
- #endif /* LOCKREG */
-
-
-
- /*
- *----------------------------------------------------------------------
- *
- * Sync_LockClear --
- *
- * Used to clear and deregister a lock before it is freed.
- * If LOCKREG is not defined then this macro does nothing.
- *
- * Results:
- * None.
- *
- * Side effects:
- * The lock is deregistered.
- *
- *----------------------------------------------------------------------
- */
- #ifdef LOCKREG
-
- #define Sync_LockClear(lock) \
- { \
- if (Sync_IsRegistered(lock)) { \
- Sync_CheckoutInt((Address) (lock)); \
- } \
- }
-
- #else /* LOCKREG */
-
- #define Sync_LockClear(sem)
-
- #endif /* LOCKREG */
-
- /*
- *----------------------------------------------------------------------
- *
- * Sync_AddPrior --
- *
- * When a lock is grabbed the prior lock must be added to the prior
- * types for the lock.
- * This macro does nothing if LOCKDEP is not defined.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- #ifdef LOCKDEP
-
- #define Sync_AddPrior(lockPtr) { \
- Sync_AddPriorInt((lockPtr)->type, &(lockPtr)->priorCount, \
- (lockPtr)->priorTypes, (lockPtr), (lockPtr)->holderPCBPtr); \
- }
-
- #else /* LOCKDEP */
-
- #define Sync_AddPrior(lockPtr)
-
- #endif /* LOCKDEP */
-
- /*
- *----------------------------------------------------------------------
- *
- * SyncMergePrior --
- *
- * When a lock is cleared its statistics must be added to those for
- * the type as a whole.
- * This macro does nothing if LOCKDEP is not defined.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- #ifdef LOCKDEP
-
- #define SyncMergePrior(lockPtr, regPtr) \
- { SyncMergePriorInt((lockPtr)->priorCount, (lockPtr)->priorTypes, \
- (regPtr)); }
-
- #else /* LOCKDEP */
-
- #define SyncMergePrior(lockPtr, regPtr)
-
- #endif /* LOCKDEP */
-
-
- /*
- *----------------------------------------------------------------------
- *
- * SyncDeleteCurrent --
- *
- * When we unlock a lock we have to delete it from the stack of
- * current locks.
- * If LOCKDEP is not defined then don't do anything.
- *
- * Results:
- * None.
- *
- * Side effects:
- * The lock is removed from the lock stack in the current pcb.
- *
- *----------------------------------------------------------------------
- */
-
- #ifdef LOCKDEP
-
- #define SyncDeleteCurrent(lockPtr) \
- { SyncDeleteCurrentInt((lockPtr), (lockPtr)->holderPCBPtr); }
-
- #else /* LOCKDEP */
-
- #define SyncDeleteCurrent(lockPtr)
-
- #endif /* LOCKDEP */
-
-
- /*
- *----------------------------------------------------------------------
- *
- * SyncDeadlockPanic --
- *
- * Prints out a warning message and calls panic. There is one
- * version for clean locks, and another version for printing
- * debugging information found in the locks.
- *
- * Results:
- * None.
- *
- * Side effects:
- * panic is called.
- *
- *----------------------------------------------------------------------
- */
-
- #ifdef CLEAN_LOCK
-
- #define SyncDeadlockPanic(semaphore) { \
- panic("Deadlock!!! (semaphore @ 0x%x)\n", (int)(semaphore)); \
- }
-
- #else /* CLEAN_LOCK */
-
- #define SyncDeadlockPanic(semaphore) { \
- panic("Deadlock!!!(%s @ 0x%x)\nHolder PC: 0x%x Current PC: 0x%x\nHolder PCB @ 0x%x Current PCB @ 0x%x\n", \
- (semaphore)->name,(int)(semaphore),(int)(semaphore)->holderPC,\
- (int) Mach_GetPC(),(int) (semaphore)->holderPCBPtr, \
- (int) Proc_GetCurrentProc()); \
- }
-
- #endif /* CLEAN_LOCK */
-
- /*
- *----------------------------------------------------------------------
- *
- * Sync_RecordHit --
- *
- * If LOCKREG is defined then the hit field of the lock
- * is incremented.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- #ifndef LOCKREG
-
- #define Sync_RecordHit(lock) {}
-
- #else /* LOCKREG */
-
- #define Sync_RecordHit(lock) { (lock)->hit++; }
-
- #endif /* LOCKREG */
-
- /*
- *----------------------------------------------------------------------
- *
- * Sync_RecordMiss --
- *
- * If LOCKREG is defined then the miss field of the lock
- * is incremented.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
- #ifndef LOCKREG
-
- #define Sync_RecordMiss(lock) {}
-
- #else /* LOCKREG */
-
- #define Sync_RecordMiss(lock) { (lock)->miss++; }
-
- #endif /* LOCKREG */
-
- /*
- *----------------------------------------------------------------------
- *
- * SyncStorDbgInfo --
- *
- * If CLEAN_LOCK isn't defined then store debugging information
- * in the lock. If "lockedByMacro" is TRUE, the lock was obtained
- * via a macro, so we record the current PC, which is in the
- * function that invoked the macro. If it's FALSE, the lock was
- * obtained by a function whose sole job is to obtain the lock,
- * so we want to record the PC of that function's caller.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
- #ifdef CLEAN_LOCK
-
- #define Sync_StoreDbgInfo(semaphore, lockedByMacro) {}
-
- #else /* CLEAN_LOCK */
-
- #define Sync_StoreDbgInfo(semaphore, lockedByMacro) { \
- if ((lockedByMacro) == TRUE) { \
- (semaphore)->holderPC = (Address) Mach_GetPC(); \
- } else { \
- (semaphore)->holderPC = (Address) Mach_GetCallerPC(); \
- } \
- (semaphore)->holderPCBPtr = Proc_GetCurrentProc(); \
- }
-
- #endif /* CLEAN_LOCK */
- #endif /* _SYNC */
-
-